<script setup>
import { computed, onBeforeUnmount, onMounted, reactive, ref, watch } from 'vue'
import { cloneDeep } from 'lodash'
import { Message, Modal, Notification } from '@arco-design/web-vue'
import { getParamSpinner, getProcessParam } from '@/api/fault/fault'
import { getTaskTrendDataList } from '@/api/trend/trend'
import dayjs from 'dayjs'
import LineChart from '@/components/chart/lineChart.vue'
import FaultReport from '@/views/trendForecast/components/FaultReport.vue'
import Template from '@/views/modelInference/template.vue'
import { exportWord } from '@/utils/word'
import html2Canvas from 'html2canvas'
import {
  delTaskAPI,
  getAllFaultModelAPI,
  getFaultTaskPageAPI,
  getTaskDetailInfoAPI,
  getTaskExecResultAPI,
  runOnlineExecTaskAPI,
  startTaskAPI,
  stopTaskAPI
} from '@/api/newFault'
import vue3Cron from '@/components/vue3-cron/index.vue'
import { getRPNType } from '@/utils'

const props = defineProps({
  satelliteInfo: Object
})

const CHART_QUERY_FORM = {
  satelliteCode: '',
  paramCode: '',
  paramCodes: [],
  startTime: '',
  endTime: '',
  childTaskId: '',
  taskId: '',
  childId: '',
  status: null
}

const RESULT_FORM = {
  satelliteName: '',
  fractionTime: '',
  paramCode: '',
  timeSlot: ''
}

const CONCLUSION_DATA = {
  timeSlot: '',
  count: ''
}

const AUTO_FORM = {
  taskName: '',
  satelliteCode: '',
  satelliteName: '',
  satelliteId: '',
  paramCode: '',
  modelName: '',
  startTime: '',
  endTime: '',
  cron: '',
  dateRange: []
}

const chartQueryForm = ref(cloneDeep(CHART_QUERY_FORM))
const resultForm = ref(cloneDeep(RESULT_FORM))
const conclusionData = ref(cloneDeep(CONCLUSION_DATA))

const scroll = {
  x: '1200px',
  y: '100%'
}
const chartLoading = ref(false)
const dataSource = ref({
  xAxisType: 'time',
  xAxis: [],
  yAxis: [
    {
      name: '原始数据',
      color: '#0ab7b9',
      data: []
    },
    {
      name: '预测数据',
      color: 'orange',
      data: []
    },
    {
      name: '对比数据',
      color: '#800101',
      data: []
    }
  ]
})

const columns = [
  {
    title: '任务名称',
    dataIndex: 'taskName'
  },
  {
    title: '查询数据时间段',
    dataIndex: 'dateRange',
    render: ({ record }) => {
      return `${dayjs(record.startTime).format('YYYY-MM-DD HH:mm:ss')} 至 ${dayjs(record.endTime).format('YYYY-MM-DD HH:mm:ss')}`
    },
    width: 320
  },
  {
    title: '运行状态',
    slotName: 'status',
    render: ({ record }) => {
      return record.status === false ? '已停止' : '运行中'
    },
    bodyCellStyle: (record) => {
      return record.status === false ? { color: '#f53f3f' } : { color: '#00b42a' }
    }
  },
  {
    title: '参数名称',
    dataIndex: 'paramCode'
  },
  {
    title: '模型名称',
    dataIndex: 'modelName'
  },
  {
    title: 'cron表达式',
    dataIndex: 'cron'
  },
  {
    title: '操作',
    slotName: 'action',
    width: 225,
    fixed: 'right',
    align: 'center'
  }
]
const tableLoading = ref(false)
const autoTaskPageData = ref([])
const pagination = ref({
  pageNum: 1,
  pageSize: 10,
  total: 0
})

const loadList = async () => {
  try {
    tableLoading.value = true
    const params = {
      satelliteCode: autoForm.value.satelliteCode,
      taskName: queryForm.value.taskName,
      page: pagination.value.pageNum,
      pageSize: pagination.value.pageSize,
      isSchedule: true
    }
    const { code, data } = await getFaultTaskPageAPI(params)
    if (code === 200) {
      autoTaskPageData.value = data.list
      pagination.value.total = Number(data.total)
    }
  } catch (e) {
    console.log(e)
  } finally {
    tableLoading.value = false
  }
}

const selectedKeys = ref([])
const rowSelection = reactive({
  type: 'checkbox',
  showCheckedAll: true,
  onlyCurrent: false
})

const handleBatchDel = () => {
  if (selectedKeys.value.length === 0) return Message.warning('请勾选需要删除的任务')

  Modal.confirm({
    title: '提示',
    content: `是否确认删除这些任务?`,
    okText: '确认',
    cancelText: '取消',
    onOk: async () => {
      try {
        const { code, message } = await delTaskAPI(selectedKeys.value)
        if (code === 200) {
          Message.success('删除成功')
        } else {
          Message.error(message || '删除失败')
        }
      } catch (e) {
        console.log(e)
      } finally {
        await loadList()
      }
    }
  })
}

const handlePageChange = (page) => {
  pagination.value.pageNum = page
  loadList()
}

const handlePageSizeChange = (size) => {
  pagination.value.pageSize = size
  loadList()
}

const handleDelete = (record) => {
  Modal.confirm({
    title: '提示',
    content: `是否确认删除该任务?`,
    okText: '确认',
    cancelText: '取消',
    onOk: async () => {
      try {
        const { code, message } = await delTaskAPI([record.id])
        if (code === 200) {
          Message.success('删除成功')
        } else {
          Message.error(message || '删除失败')
        }
      } catch (e) {
        console.log(e)
      } finally {
        await loadList()
      }
    }
  })
}
const autoFormLoading = ref(false)
const autoFormRef = ref(null)
const runOnline = async (data) => {
  if (!autoFormRef.value) return false
  const res = await autoFormRef.value.validate()
  if (res !== undefined) return false
  console.log('values', data.values)
  try {
    autoFormLoading.value = true
    const { code, data: resData } = await runOnlineExecTaskAPI(data.values)
    if (code === 200) {
      Message.success(resData || '运行成功')
    }
  } catch (e) {
    console.log(e)
  } finally {
    autoFormLoading.value = false
    await loadList()
  }
}
const queryForm = ref({
  taskName: ''
})

const autoFormRules = {
  paramCode: [{ required: true, message: '请选择参数', trigger: ['change', 'input'] }],
  dateRange: [{ required: true, message: '请选择时间段', trigger: ['change', 'input'] }],
  modelName: [{ required: true, message: '请选择模型', trigger: ['change', 'input'] }],
  taskName: [{ required: true, message: '请填写任务名称', trigger: ['change', 'input'] }],
  cron: [{ required: true, message: '请设置或填写定时器', trigger: ['change', 'input'] }]
}

const autoForm = ref(cloneDeep(AUTO_FORM))

const paramOptions = ref([])
const paramSelectLoading = ref(false)
const computedSearchSelectPlaceholder = computed(() => {
  if (!autoForm.value.satelliteId) {
    return '请先选择左侧卫星'
  } else {
    return '请选择参数'
  }
})

const handleSearch = async (queryStr) => {
  if (!autoForm.value.satelliteId) return Message.error('请先选择左侧卫星!')
  try {
    paramSelectLoading.value = true
    const { code, data } = await getParamSpinner(autoForm.value.satelliteId, queryStr)
    if (code === 200) {
      paramOptions.value = data
    }
  } catch (e) {
    console.log(e)
  } finally {
    paramSelectLoading.value = false
  }
}

const modelOptions = ref([])

const getAllFaultModel = async () => {
  try {
    modelSelectLoading.value = true
    const { code, data } = await getAllFaultModelAPI()
    if (code === 200) {
      modelOptions.value = data
    }
  } catch (e) {
    console.log(e)
  } finally {
    modelSelectLoading.value = false
  }
}

const setCron = () => {
  cronVisible.value = true
}

const processParam = async () => {
  try {
    const { code, data } = await getProcessParam({
      satelliteCode: autoForm.value.satelliteCode,
      paramCode: autoForm.value.paramCode
    })
    if (code === 200) {
      Notification.info({
        title: '提示',
        closable: true,
        content: data
      })
    }
  } catch (e) {
    console.log(e)
  }
}

const modelSelectLoading = ref(false)
const paramCodeChange = (paramCode) => {
  autoForm.value.paramCodeName = paramOptions.value.find((item) => item.telemetryCode === paramCode)?.paramName
  // 获取是否进行过数据预处理
  processParam()
}

const handleStartOrStop = async (record) => {
  const isStarted = record.status === true
  const action = isStarted ? '停止' : '启动'
  const apiFunc = isStarted ? stopTaskAPI : startTaskAPI

  const doRequest = async () => {
    try {
      const { code, data, message } = await apiFunc(record)
      if (code === 200) {
        Message.success(data || message || `${action}成功`)
      } else {
        Message.error(message || `${action}失败`)
      }
    } catch (e) {
      console.error(e)
    } finally {
      await loadList()
    }
  }

  Modal.confirm({
    title: '提示',
    content: `确定要${action}该任务吗？`,
    okText: '确认',
    cancelText: '取消',
    onBeforeOk: doRequest
  })
}

const handleQuery = () => {
  pagination.value.pageNum = 1
  pagination.value.pageSize = 10
  loadList()
}

const showDetail = ref(false)
const reportVisible = ref(false)
const cronVisible = ref(false)
const timer = ref()

const cronObj = reactive({
  cron: '',
  userSetting: null
})

const getChartsData = async () => {
  try {
    const yAxis = []
    const yData = []
    const y1Data = []
    chartLoading.value = true
    const { code, data } = await getTaskTrendDataList(chartQueryForm.value)
    if (code === 200) {
      dataSource.value.xAxis = data.xAis
      if (data.telemetryDataList && data.telemetryDataList.length > 0) {
        data.telemetryDataList.forEach((x) => {
          yAxis.push([x.time, x.value])
        })
        dataSource.value.yAxis[0].data = yAxis
      }
      if (data.taskTrendDataList && data.taskTrendDataList.length > 0) {
        data.taskTrendDataList.forEach((x) => {
          yData.push([x.time, x.value])
        })
        dataSource.value.yAxis[1].data = yData
      }
      if (data.realTimeDataList && data.realTimeDataList.length > 0) {
        data.realTimeDataList.forEach((x) => {
          y1Data.push([x.time, x.value])
        })
        dataSource.value.yAxis[2].data = y1Data
      }
      if (chartQueryForm.value.status === 1) {
        funTimer()
      }
    }
  } catch (e) {
    console.log(e)
  } finally {
    chartLoading.value = false
  }
}

const queryEcharts = async () => {
  try {
    const { code, data } = await getTaskDetailInfoAPI(chartQueryForm.value.taskId)
    if (code === 200) {
      clearInterval(timer.value)
      chartQueryForm.value.startTime = data.startTime
      chartQueryForm.value.endTime = data.endTime
      await getChartsData()
    }
  } catch (e) {
    console.log(e)
  }
}

const funTimer = () => {
  timer.value = setInterval(() => {
    queryEcharts()
  }, 10000)
}
const setDetailParams = (item) => {
  // 图表接口查询参数
  chartQueryForm.value.satelliteCode = item.satelliteCode
  chartQueryForm.value.paramCode = item.params
  chartQueryForm.value.paramCodes = [item.params]
  chartQueryForm.value.startTime = item.startTime
  chartQueryForm.value.endTime = item.endTime
  chartQueryForm.value.taskId = item.id
  chartQueryForm.value.childId = item.id
  chartQueryForm.value.childTaskId = item.name
  chartQueryForm.value.status = item.status
  // 预测分析结果设置
  resultForm.value.satelliteName = item.satelliteCode
  resultForm.value.paramCode = item.params
  resultForm.value.fractionTime = dayjs().format('YYYY/MM/DD HH:mm:ss')
  resultForm.value.timeSlot = conclusionData.value.timeSlot =
    dayjs(item.startTime).format('YYYY/MM/DD HH:mm:ss') + ' 至 ' + dayjs(item.endTime).format('YYYY/MM/DD HH:mm:ss')
}

const resetReport = () => {
  resultForm.value = cloneDeep(RESULT_FORM)
}
const resetTimer = () => {
  clearInterval(timer.value)
  timer.value = undefined
}
const resetTable = () => {
  autoTaskPageData.value = []
  pagination.value.pageNum = 1
  pagination.value.pageSize = 10
  pagination.value.total = 0
}
const resetForm = () => {
  autoForm.value = cloneDeep(AUTO_FORM)
  queryForm.value.name = ''
}
const hiddenDetail = () => {
  showDetail.value = false
  resetChart()
  resetReport()
  resetTimer()
}

const detailVisible = ref(false)

const descData = ref([
  {
    label: '当前工序控制方法',
    code: 'currentProcessControlPlan',
    value: ''
  },
  {
    label: '检测失效的能力',
    code: 'detection',
    value: ''
  },
  {
    label: '造成的影响',
    code: 'effect',
    value: ''
  },

  {
    label: '失效种类',
    code: 'failureMode',
    value: ''
  },
  {
    label: '失效发生概率',
    code: 'occurrence',
    value: ''
  },
  {
    label: '风险优先指数',
    code: 'rpn',
    value: ''
  },
  {
    label: '严重性',
    code: 'severity',
    value: ''
  },
  {
    label: '故障推断起始时间',
    code: 'startTime',
    value: ''
  },
  {
    label: '故障推断结束时间',
    code: 'endTime',
    value: ''
  },
  {
    label: '改善方案',
    code: 'recommendedAction',
    value: ''
  }
])
const handleDetail = async (record) => {
  try {
    tableLoading.value = true
    const { code, data, message } = await getTaskExecResultAPI(record.id)
    if (code === 200 && data) {
      descData.value.forEach((item) => {
        if (item.code === 'rpn') {
          item.value = getRPNType(data[item.code])
        } else {
          item.value = data[item.code] ?? '---'
        }
      })
      detailVisible.value = true
    } else {
      Message.error(data || message || '暂无详情')
    }
  } catch (e) {
    console.log(e)
  } finally {
    tableLoading.value = false
  }
  /* // 设置参数
  setDetailParams(record)
  // 获取图表信息
  await queryEcharts()
  showDetail.value = true */
}

const resetChart = () => {
  dataSource.value.xAxis = []
  dataSource.value.yAxis[0].data = []
  dataSource.value.yAxis[1].data = []
}
const getBase64Sync = () => {
  return new Promise((resolve, reject) => {
    const targetDom = document.querySelector('#echartsDom')
    html2Canvas(targetDom, {
      allowTaint: true,
      taintTest: false,
      useCORS: true,
      dpi: window.devicePixelRatio * 4, // 将分辨率提高到特定的DPI 提高四倍
      scale: 4 // 按比例增加分辨率
    }).then((canvas) => {
      resolve(canvas.toDataURL())
    })
  })
}
const handleDownload = async () => {
  const title = '趋势预测-异常分析结果'
  const arr = [
    {
      number: 1,
      time: conclusionData.value.timeSlot,
      length: conclusionData.value.count
    }
  ]
  const data = {
    templateTitle: title, // 模版标题
    satelliteName: resultForm.value.satelliteName, // 卫星名称
    fractionTime: resultForm.value.fractionTime, // 检测时间
    paramCode: resultForm.value.paramCode, // 参数代号
    telemetryTime: resultForm.value.timeSlot, // 遥测时间
    image: await getBase64Sync(),
    table: arr
  }
  // 控制导出的word图片大小
  const imgSize = {
    image: [596, 300]
  }
  exportWord(`${import.meta.env.VITE_APP_BASE_ASSETS}docs/trendTemplate.docx`, data, title + '.docx', imgSize)
}

const resetTabs = () => {
  resetChart()
  resetReport()
  resetTimer()
  resetTable()
  resetForm()
}

const legendSelectValue = ref({})
const handleLegendChange = (val) => {
  legendSelectValue.value = val
}
const dateRangeChange = (date) => {
  if (date) {
    autoForm.value.startTime = date[0]
    autoForm.value.endTime = date[1]
  } else {
    autoForm.value.startTime = ''
    autoForm.value.endTime = ''
  }
}

const changeCron = (cron) => {
  if (cron) {
    autoForm.value.cron = cron[0]
  }
}

const closeCron = () => {
  cronVisible.value = false
}

watch(
  () => props.satelliteInfo,
  (newVal) => {
    resetTabs()
    autoForm.value.paramCode = ''
    if (newVal) {
      autoForm.value.satelliteId = newVal.satelliteId
      autoForm.value.satelliteCode = newVal.code
      autoForm.value.satelliteName = newVal.name
      handleSearch('')
      loadList()
    } else {
      autoForm.value.satelliteId = autoForm.value.satelliteCode = autoForm.value.satelliteName = ''
      paramOptions.value = []
    }
  },
  { deep: true }
)
onMounted(() => {
  if (props.satelliteInfo?.satelliteId) {
    autoForm.value.satelliteId = props.satelliteInfo.satelliteId
    autoForm.value.satelliteCode = props.satelliteInfo.code
    autoForm.value.satelliteName = props.satelliteInfo.name
    handleSearch('')
    loadList()
  }
  getAllFaultModel()
})

onBeforeUnmount(() => {
  resetTimer()
})
</script>

<template>
  <div class="tabs-auto">
    <div class="tabs-content-left" ref="manualChartsDomRef">
      <div v-show="!showDetail" class="table-card">
        <div class="table-card-header">
          <div class="table-card-header-left">
            <a-form :model="queryForm" @submit="handleQuery" layout="inline">
              <a-form-item field="taskName" label="任务名称" style="margin-right: 0">
                <a-input v-model="queryForm.taskName" placeholder="任务名称" allow-clear />
              </a-form-item>
              <a-form-item>
                <a-button type="primary" html-type="submit">
                  <template #icon>
                    <icon-search />
                  </template>
                  查询
                </a-button>
              </a-form-item>
            </a-form>
          </div>
          <div class="table-card-header-right">
            <a-button type="primary" @click="handleBatchDel">
              <template #icon>
                <icon-delete />
              </template>
              批量删除
            </a-button>
          </div>
        </div>
        <div class="table-wrapper">
          <a-table
            row-key="id"
            :columns="columns"
            :data="autoTaskPageData"
            :pagination="false"
            :scroll="scroll"
            :scrollbar="false"
            :loading="tableLoading"
            :row-selection="rowSelection"
            v-model:selectedKeys="selectedKeys"
          >
            <template #action="{ record }">
              <a-button status="success" size="mini" type="text" @click="handleDetail(record)">
                <template #icon>
                  <icon-file />
                </template>
                详情
              </a-button>
              <a-button status="normal" size="mini" type="text" @click="handleStartOrStop(record)">
                <template #icon>
                  <icon-play-circle-fill v-if="record.status === false" />
                  <icon-pause-circle-fill v-else />
                </template>
                {{ record.status === false ? '启动' : '停止' }}
              </a-button>
              <a-button status="danger" size="mini" type="text" @click="handleDelete(record)">
                <template #icon>
                  <IconDelete />
                </template>
                删除
              </a-button>
            </template>
          </a-table>
        </div>
        <div class="table-card-footer">
          <a-pagination
            :total="pagination.total"
            :current="pagination.page"
            :page-size="pagination.pageSize"
            show-total
            show-jumper
            show-page-size
            @change="handlePageChange"
            @page-size-change="handlePageSizeChange"
          />
        </div>
      </div>
      <div v-show="showDetail" class="detail-card">
        <div>
          <a-button type="primary" @click="reportVisible = true">预测分析</a-button>
        </div>
        <div class="detail-card-main">
          <line-chart :chart-data="dataSource" :loading="chartLoading" @legend-change="handleLegendChange" />
        </div>
        <div class="detail-card-footer">
          <a-button type="primary" @click="hiddenDetail">
            <template #icon>
              <icon-backward />
            </template>
            返回
          </a-button>
        </div>
      </div>
    </div>
    <div class="tabs-content-right">
      <div style="text-align: center">
        <div style="font-size: 18px; font-weight: bold">配置</div>
        <a-divider style="margin: 4px 0" dashed />
      </div>
      <a-spin :loading="autoFormLoading" style="height: calc(100% - 36px)">
        <a-form :model="autoForm" @submit="runOnline" :rules="autoFormRules" layout="vertical" ref="autoFormRef">
          <a-form-item field="paramCode" label="选择参数">
            <a-select
              :loading="paramSelectLoading"
              :placeholder="computedSearchSelectPlaceholder"
              @search="handleSearch"
              :filter-option="false"
              v-model="autoForm.paramCode"
              @change="paramCodeChange"
              allow-search
              allow-clear
            >
              <a-option v-for="item of paramOptions" :key="item.telemetryCode" :value="item.telemetryCode"
                >{{ item.paramName }}
              </a-option>
            </a-select>
          </a-form-item>
          <a-form-item field="dateRange" label="查询数据时间段">
            <a-range-picker v-model="autoForm.dateRange" showTime allow-clear @change="dateRangeChange" />
          </a-form-item>
          <a-form-item field="modelName" label="选择模型">
            <a-select :loading="modelSelectLoading" v-model="autoForm.modelName" placeholder="请选择模型" allow-clear>
              <a-option v-for="item of modelOptions" :key="item.modName" :value="item.modName"
                >{{ item.modName }}
              </a-option>
            </a-select>
          </a-form-item>
          <a-form-item field="taskName" label="任务名称">
            <a-input v-model="autoForm.taskName" placeholder="请填写任务名称" allow-clear />
          </a-form-item>
          <a-form-item field="cron" label="定时器(cron)">
            <a-input v-model="autoForm.cron" placeholder="请填写或设置cron定时器" allow-clear />
            <a-button type="primary" style="margin-left: 16px" @click="setCron">设置</a-button>
          </a-form-item>
          <a-form-item class="form-bottom">
            <a-button type="primary" html-type="submit">上线运行</a-button>
          </a-form-item>
        </a-form>
      </a-spin>
    </div>
  </div>
  <a-modal v-model:visible="reportVisible" title="趋势预测报告" hide-cancel width="60%">
    <fault-report
      :result-form="resultForm"
      :data-source="dataSource"
      :conclusion-data="conclusionData"
      :legend-state="legendSelectValue"
    />
    <template #footer>
      <a-button type="primary" @click="handleDownload">
        <template #icon>
          <icon-download />
        </template>
        下载报告
      </a-button>
    </template>
  </a-modal>
  <a-modal v-model:visible="cronVisible" title="设置定时器" width="650px" :footer="false">
    <vue3-cron :cron-value="cronObj" @change-cron="changeCron" @close="closeCron" />
  </a-modal>
  <a-modal v-model:visible="detailVisible" title="任务执行详情" ok-text="关闭" hide-cancel>
    <a-descriptions :data="descData" bordered size="large" :column="1" />
  </a-modal>
</template>

<style scoped lang="less">
@import '@/views/failureEffectsAnalysis/style/auto';
</style>
